home account info subscribe login search FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

Bug Proofing Visual Basic: A Guide to Error Handling and Prevention
(Publisher: John Wiley & Sons, Inc.)
Author(s): Rod Stephens
ISBN: 0471323519
Publication Date: 11/01/98

Search this book:
 
Previous Table of Contents Next


Don’t Use One Input for Multiple Purposes

Do not use the same input variable for multiple purposes. For example, you could write a routine that draws lines, circles, and ellipses. The first parameter indicates the type of shape. For circles, the next four parameters are the coordinates of the line’s end points. For circles, the next three parameters give the coordinates of the circle’s center and its radius. For ellipses, the next four parameters give the ellipse’s minimum and maximum X and Y values.

These parameters mean different things under different circumstances and that makes them confusing. Parameters should not have different meanings in different parts of the routine.

One solution is to redefine the parameters so they have consistent meanings. In this case, the four parameters after the first could specify the minimum and maximum X and Y values for the shape no matter which shape is being drawn.

Another solution is to create separate parameters for each shape. To draw a line, for example, the calling routine would omit the other parameters.

Perhaps the best solution is to break this routine into three separate routines, one for each shape. The combined routine really performs three very different functions and there is little profit in making it one subroutine anyway.

Visual Basic’s Line statement is a good example of a routine asked to do too much. The Line statement can draw either a line or a rectangle depending on whether the third parameter contains a B. Conceptually, drawing a line and drawing a rectangle are not similar tasks. The only thing they have in common is that they can be specified using the coordinates of two points. Because they are conceptually different, these tasks should be performed by separate routines.

Don’t Use One Output for Multiple Purposes

Do not use the same output variable for multiple purposes. You could write a ControlValue function that returns a variant containing a ScrollBar’s numeric value if the parameter is a ScrollBar, a TextBox’s string value if the parameter is a TextBox, a RadioButton’s Boolean state if the parameter is a RadioButton, and so forth.

Resist the temptation. This function would be very confusing to use because it returns values that are conceptually very different.

Keep Separate Tasks Separate

Make each routine perform just one conceptual task. If it performs more than one task, using it can be confusing. Visual Basic’s Circle method is a good example. It allows you to draw both circles and ellipses.

To draw a circle, the program passes the Circle method the coordinates of the circle’s center and its radius. That is a reasonable way to specify a circle and makes perfect sense.

To draw an ellipse, you add another parameter containing the ellipse’s aspect ratio. That is remarkably counterintuitive. Probably very few programmers think of drawing ellipses using the center of the ellipse, a radius, and an aspect ratio.

The radius and aspect ratio parameters do not even always specify the same values. If the aspect ratio is greater than 1.0, the radius gives the ellipse’s height and the width is the radius divided by the aspect ratio. If the aspect ratio is less than 1.0, the radius gives the ellipse’s width and the height is the radius times the aspect ratio.

This ridiculous situation arises because the developers of Visual Basic were thinking of circles and ellipses as two different kinds of objects. The center and radius parameters make drawing circles intuitive. The aspect ratio parameter is tacked on to make the routine draw ellipses as well.

The developers could have redefined the routine’s functionality so it performed one conceptual task. For example, they could have built a single Ellipse routine to draw ellipses. It could take as parameters the ellipse’s minimum and maximum X and Y coordinates. In fact, this is the way the API Ellipse function works. Because a circle is just a special kind of ellipse, this routine draws circles without any extra confusion. If the difference in the X coordinates is the same as the difference in the Y coordinates, the result is a circle.

Alternatively, the Ellipse routine could take as parameters the coordinates of the ellipse’s center and its width and height. In this case, if the width and height are the same, the result is a circle.

Finally, this confusion could have been completely avoided by using separate Circle and Ellipse routines.

Do not cause similar confusion in your programs. Make each routine perform a single conceptual task. If a routine performs several functions, break it into two or more separate routines that each performs a single task.

Examine Decisions Closely

Whenever a program makes a choice, it can make the wrong choice. Decisions are more prone to errors than simple calculations, so you should study decisions carefully.

An If statement clearly makes a decision. Select statements are structurally very similar to long If Then Else statements, so they also make decisions.

Loops make decisions in less obvious ways. Every time a For or Do loop executes, Visual Basic checks the loop’s ending condition to see if the loop should stop. The logic behind these decisions can be confusing in a Do While loop where the exit condition is complicated.

Exit statements represent the decision to break out of a loop or routine, so you should consider them carefully. Finally, On Error statements set the stage for a later decision to go to a particular error handler when an error occurs.

Carefully examine all of these decision points so you are sure they make sense.

Use FreeFile

Use FreeFile to obtain an unused file number before you open a file. It is remarkable how many Visual Basic programmers simply use the number 1 for all of their file operations. If you use a constant instead of FreeFile and you ever integrate your code with another routine that uses the same file number, you may encounter strange bugs.

Assigning the file number to a variable also lets you use a meaningful name to represent the file. The following code opens a data file and reads the number of items stored in the file. It then uses the ReadItem subroutine to read the items from the file. If ReadItem also uses FreeFile to find unused file numbers, it can open other files if it needs to without interfering with this routine.

Dim input_file As Integer
Dim num_items As Integer
Dim item As Integer

    ' Open the data file.    
    input_file = FreeFile    
    Open input_file_name For Input As input_file
    
    ' Read the number of items.    
    Input #input_file, num_items
    
    ' Read the items.    
    For i = 1 To num_items
       ' Use the ReadItem routine to read the next        
       ' item from the file.        
       ReadItem input_file    
    Next i
    
    ' Close the data file.
    Close input_file


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.